package picture

import (
	"bytes"
	"errors"
	"image"
	"image/draw"
	"image/jpeg"
	"image/png"
	"net/http"
	"os"
	"strconv"
	"task/logger"
	"time"
	"util"
)

type Picture struct {
	Img    *image.Gray
	Format string
	Url    string
}

type SmallImg struct {
	Img    image.Image
	ImgNo  int
	Format string
}

// func (pic Picture) GetSize() (w int, h int) {
// 	b := img.Bounds()
// 	w := b.Max.X
// 	h := b.Max.Y
// }

func (img *SmallImg) Encode() (buf *bytes.Buffer, err error) {
	buf = new(bytes.Buffer)
	if img.Format == "png" {
		err = png.Encode(buf, img.Img)
		// util.CheckErr(err)
	} else if img.Format == "jpg" || img.Format == "jpeg" {
		err = jpeg.Encode(buf, img.Img, nil)
	} else {
		panic("bad image png")
	}
	return
}

/*
Get Img
*/
func GetImg(url string) (pic *Picture) {
	pic = new(Picture)
	logger.Info("Get Image:", url)
	pic.Url = url
	c := &http.Client{
		Timeout: 500 * time.Second,
	}
	resp, err := c.Get(url)
	util.CheckErr(err)
	defer resp.Body.Close()
	img, format, err := image.Decode(resp.Body)
	util.CheckErr(err)
	pic.Format = format
	size := img.Bounds()
	pic.Img = image.NewGray(size)
	draw.Draw(pic.Img, size, img, img.Bounds().Min, draw.Src)
	logger.Info("end get Image:", url)
	return
	// return img, format
}

/*
get small img position by so
*/
func (pic *Picture) GetPicLine() (result [][]int) {
	result = getImgLineBySO(pic.Img)
	return
}

/*
Cut small img from picture
*/
func (pic *Picture) CutPic(pos [][]int, path string) (result []*SmallImg) {
	// 切图
	var err error
	for k, v := range pos {
		// img_end.
		if len(v) != 4 {
			panic("bad case for postion!")
		}
		simg := new(SmallImg)
		simg.Format = pic.Format
		simg.ImgNo = k
		simg.Img, err = imgCopy(pic.Img, v[0], v[1], v[2], v[3])
		if err == nil {
			result = append(result, simg)
			f, _ := os.Create(path + strconv.Itoa(k) + ".png") //创建文件
			defer f.Close()
			png.Encode(f, simg.Img)
		} else {
			logger.Error("CutImag:", err)
		}
	}
	return
}

func imgCopy(src image.Image, x, y, x2, y2 int) (image.Image, error) {
	var subImg image.Image
	if rgbImg, ok := src.(*image.YCbCr); ok {
		subImg = rgbImg.SubImage(image.Rect(x, y, x2, y2)).(*image.YCbCr) //图片裁剪x0 y0 x1 y1
	} else if rgbImg, ok := src.(*image.RGBA); ok {
		subImg = rgbImg.SubImage(image.Rect(x, y, x2, y2)).(*image.RGBA) //图片裁剪x0 y0 x1 y1
	} else if rgbImg, ok := src.(*image.NRGBA); ok {
		subImg = rgbImg.SubImage(image.Rect(x, y, x2, y2)).(*image.NRGBA) //图片裁剪x0 y0 x1 y1
	} else if rgbImg, ok := src.(*image.Gray); ok {
		subImg = rgbImg.SubImage(image.Rect(x, y, x2, y2)).(*image.Gray) //图片裁剪x0 y0 x1 y1
	} else {
		return subImg, errors.New("图片解码失败")
	}
	return subImg, nil
}
